//$URL: http://dasding.googlecode.com/svn/trunk/data/dao/mongoDB/src/test/java/de/piratech/dasding/data/mongo/generator/CreateTestData.java $
//$Id: CreateTestData.java 133 2013-04-19 20:55:09Z krieg.maria@gmail.com $
/*
 * Copyright 2012 Piratech.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.piratech.dasding.data.mongo.generator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import de.piratech.dasding.data.Action;
import de.piratech.dasding.data.ActionCategory;
import de.piratech.dasding.data.Event;
import de.piratech.dasding.data.EventCategory;
import de.piratech.dasding.data.Location;
import de.piratech.dasding.data.User;
import de.piratech.dasding.data.User.USER_ROLE;
import de.piratech.dasding.data.database.ActionData;
import de.piratech.dasding.data.database.Database;
import de.piratech.dasding.data.database.DatabaseException;
import de.piratech.dasding.data.database.EventData;
import de.piratech.dasding.data.database.mongo.AbstractMongoTest;
import de.piratech.dasding.data.database.mongo.MongoImpl;
import de.piratech.dasding.data.helper.PasswordHelper;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class CreateTestData extends AbstractMongoTest {

  protected static final String TEST_PROPERTIES = "mongo2.properties";

  @Autowired
  MongoImpl couch;
  List<EventCategory> eventCategories = new ArrayList<EventCategory>();
  List<ActionCategory> actionCategories = new ArrayList<ActionCategory>();

  @Before
  public void before() throws DatabaseException {

    List<Action> actions = couch.getActionData().getActions();
    for (Action actionCategory : actions) {
      couch.getActionData().deleteAction(actionCategory);
    }

    List<ActionCategory> categories = couch.getActionCategoryData()
        .getCategories();
    for (ActionCategory actionCategory : categories) {
      couch.getActionCategoryData().deleteActionCategory(actionCategory);
    }

    List<Event> events = couch.getEventData().getEvents();
    for (Event actionCategory : events) {
      couch.getEventData().deleteEvent(actionCategory);
    }

    List<EventCategory> eventCategores = couch.getEventCategoryData()
        .getCategories();
    for (EventCategory category : eventCategores) {
      couch.getEventCategoryData().deleteEventCategory(category);
    }

    List<User> users = couch.getUserData().getUsers();
    for (User actionCategory : users) {
      couch.getUserData().deleteUser(actionCategory);
    }

    List<Location> locations = couch.getLocationData().getLocations();
    for (Location actionCategory : locations) {
      couch.getLocationData().deleteLocation(actionCategory);
    }

  }

  @Test
  public void createTestData() throws DatabaseException {
    User createUser = createUser();
    createActionCategories(createUser);
    createEventCategories(createUser);

    createEvents(couch, createUser);
  }

  private User createUser() throws DatabaseException {
    User admin = getValidUser();
    admin.getRoles().add(USER_ROLE.USER);
    admin.getRoles().add(USER_ROLE.ADMIN);
    admin.setName("admin");
    admin.setPassword(PasswordHelper.getCryptedPassword("secret",
        admin.getName()));

    User user = getValidUser();
    user.getRoles().add(USER_ROLE.USER);
    user.setName("user");
    user.setPassword(PasswordHelper.getCryptedPassword("secret", user.getName()));
    couch.getUserData().createUser(user);
    
    return couch.getUserData().createUser(admin);

  }

  private void createEventCategories(User createUser) throws DatabaseException {
    EventCategory event1 = getValidEventCategory(createUser);
    event1.setName("Demo");
    event1
        .setDescription("Etwas ist scheiße und diese Veranstaltung soll darauf aufmerksam machen.");
    event1.setVerified(true);

    EventCategory event2 = getValidEventCategory(createUser);
    event2.setName("Socializing");
    event2
        .setDescription("Ein Treffen bei dem man einfach nur eine schöne Zeit zusammen verbringt.");
    event2.setVerified(true);

    EventCategory event3 = getValidEventCategory(createUser);
    event3.setName("Barcamp");
    event3
        .setDescription("Treffen zu einem bestimmten Thema um darüber zu diskutieren und sich auszutauschen.");
    event3.setVerified(true);

    EventCategory event4 = getValidEventCategory(createUser);
    event4.setName("Was illegales");
    event4
        .setDescription("Das ist eine Eventkategory, die garantiert niemals freigeschalten und für alle zugänglich gemacht wird.");
    event4.setVerified(false);

    eventCategories.add(couch.getEventCategoryData()
        .createEventCategory(event1));
    eventCategories.add(couch.getEventCategoryData()
        .createEventCategory(event2));
    eventCategories.add(couch.getEventCategoryData()
        .createEventCategory(event3));
    eventCategories.add(couch.getEventCategoryData()
        .createEventCategory(event4));
  }

  private void createActionCategories(User createUser) throws DatabaseException {

    ActionCategory cat1 = getValidActionCategory(createUser);
    cat1.setName("Kochen");
    cat1.setDescription("Lebenmittel klein schnibbeln und in einen Topf tun. Den Topf auf eine heiße Herdplatte stellen und so lange umrühren bis alles weich ist");
    cat1.setVerified(true);

    ActionCategory cat2 = getValidActionCategory(createUser);
    cat2.setName("Transportieren");
    cat2.setDescription("Etwas wahrscheinlich großes oder schweres von A nach B fahren.");
    cat2.setVerified(true);

    ActionCategory cat3 = getValidActionCategory(createUser);
    cat3.setName("Flyer verteilen");
    cat3.setDescription("Alle Flyer verteilen. Egal an wen.");
    cat3.setVerified(true);

    ActionCategory cat4 = getValidActionCategory(createUser);
    cat4.setName("Was illegales");
    cat4.setDescription("Das ist eine Actionkategory, die garantiert niemals freigeschalten und für alle zugänglich gemacht wird.");
    cat4.setVerified(false);

    actionCategories.add(couch.getActionCategoryData().createActionCategory(
        cat1));
    actionCategories.add(couch.getActionCategoryData().createActionCategory(
        cat2));
    actionCategories.add(couch.getActionCategoryData().createActionCategory(
        cat3));
    actionCategories.add(couch.getActionCategoryData().createActionCategory(
        cat4));

  }

  private void createEvents(MongoImpl couch, User user)
      throws DatabaseException {
    String[][] events1 = new String[][] { { "Event am Fernsehturm",
        "13.409286", "52.520739" } };
    createEvents(events1, eventCategories.get(0), 3, user);
    String[][] events2 = new String[][] { { "Event am Hackeschen Markt",
        "13.402591", "52.523036" } };
    createEvents(events2, eventCategories.get(1), 3, user);
    String[][] events3 = new String[][] { { "Event in den Rosenhöfen",
        "13.402269", "52.524460" } };
    createEvents(events3, eventCategories.get(2), 3, user);
    String[][] events4 = new String[][] { { "Event am SEZ", "13.446000",
        "52.526679" } };
    createEvents(events4, eventCategories.get(3), 3, user);

  }

  private void createEvents(String[][] events, EventCategory category,
      int count, User user) throws DatabaseException {
    EventData eventData = couch.getEventData();

    for (int i = 0; i < events.length; i++) {
      Event event = getValidEvent(user, category);
      event.setResponsible(user);
      Location location = event.getLocation();
      location.setId(null);
      Location createLocation2 = couch.getLocationData().createLocation(
          location);
      event.setLocation(createLocation2);
      Event createEvent = eventData.createEvent(event);
      createEvent.setActions(createActions(user, createEvent));
      eventData.updateEvent(createEvent);
    }

  }

  private Event getValidEvent(User user, EventCategory category) {
    Event event = getValidEvent();
    event.setContact(user);
    event.setCategory(category);
    return event;
  }

  private List<Action> createActions(User user, Event event)
      throws DatabaseException {
    List<Action> newActions = new ArrayList<Action>();
    newActions.addAll(createActions(actionCategories.get(0), 1, user, event));
    newActions.addAll(createActions(actionCategories.get(1), 1, user, event));
    newActions.addAll(createActions(actionCategories.get(2), 1, user, event));
    newActions.addAll(createActions(actionCategories.get(3), 1, user, event));
    return newActions;
  }

  private Collection<? extends Action> createActions(ActionCategory category,
      int count, User user, Event event) throws DatabaseException {
    List<Action> actions = new ArrayList<Action>();
    ActionData actionData = couch.getActionData();
    for (int i = 0; i < count; i++) {
      Action action = getValidAction(category, user, event);
      action.setResponsible(user);

      Location createLocation = couch.getLocationData().createLocation(
          action.getLocation());
      action.setLocation(createLocation);
      actions.add(actionData.createAction(action));
    }
    return actions;
  }

  @Configuration
  public static class DefaultConfig {

    @Bean
    public Database Database() {
      return new MongoImpl();
    }

    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
      PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
      configurer.setLocations(new Resource[] { new ClassPathResource(
          TEST_PROPERTIES) });
      return configurer;
    }

  }
}
